package com.service.config.utils;


import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisUtil {

    @Resource
    public StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedisTemplate redisTemplate;

    // 批量删除对应的value
    public void deleteAll(String... keys) {
        for (String key : keys) {
            delete(key);
        }
    }

    /**
     * 递增
     *
     * @param key 键
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key 键
     * @return
     */
    public Long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    // 批量删除key
    public void deletePattern(String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0)
            redisTemplate.delete(keys);
    }

    // 删除指定key的value
    public void delete(String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    // 判断缓存中是否有对应的value
    public boolean exists(String key) {
        return redisTemplate.hasKey(key);
    }

    // 读取缓存
    public Object get(String key) {
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        return operations.get(key);
    }

    public Boolean setString(String key, Object value) {
        boolean flag = false;
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception E) {
            return flag;
        }

    }

    // 写入缓存
    public boolean set(String key, Object value) {
        boolean flag = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    // 写入缓存
    public boolean sets(String key, Object value, Long expireTime) {
        boolean flag = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.HOURS);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    // 获取某个key的剩余过期时间
    public long residualExpirationTime(String key) {
        return stringRedisTemplate.getExpire(key);
    }
    // 获取某个key的剩余过期时间
    public Set<String> redisLike(String key) {
        return stringRedisTemplate.keys("*"+key);
    }
    // 获取某个key的剩余过期时间
    public Set<String> redisLikeById(String key) {
        return stringRedisTemplate.keys(key+"*");
    }

    // 当key不存在时，为key赋值
    public boolean setValue(String key, String value) {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        return ops.setIfAbsent(key, value);
    }
    // 当key不存在时，为key赋值
    public String getValue(String key) {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        return ops.get(key);
    }
    // 为key赋值，同时设置过期时间

    /**
     *
     * @param key
     * @param i 选值 1--分钟； 3--毫秒； 4--小时； 5--天； 6--微妙； 默认--秒；
     * @param value
     * @param time
     */
    public void set(String key, int i ,String value, long time) {
        BoundValueOperations<String, String> ops = stringRedisTemplate.boundValueOps(key);
        switch (i){
            case 1 :
                //分钟
                ops.set(value, time, TimeUnit.MINUTES);
                break; //可选
            case 3 :
                //毫秒
                ops.set(value, time, TimeUnit.MILLISECONDS);
                break; //可选
            case 4:
                //小时
                ops.set(value, time, TimeUnit.HOURS);
                break; //可选
            case 5 :
                //天
                ops.set(value, time, TimeUnit.DAYS);
                break; //可选
            case 6 :
                //微妙
                ops.set(value, time, TimeUnit.MICROSECONDS);
                break; //可选
            default : //可选
                //秒
                ops.set(value, time, TimeUnit.SECONDS);
        }
    }

    /**
     * 设置过期时间为小时制
     * @param key
     * @param value
     * @param time
     */
    public void set1(String key, String value, long time) {
        BoundValueOperations<String, String> ops = stringRedisTemplate.boundValueOps(key);
        ops.set(value, time, TimeUnit.HOURS);
    }

    // 判断某个key是否存在
    public boolean exist(String key) {
        return stringRedisTemplate.hasKey(key);
    }

    // 同redis命令的leftPush
    public void leftPush(String key, String value) {
        stringRedisTemplate.boundListOps(key).leftPush(value);
    }
    // 设置redis 的list过期时间
    public void setExpire(String key, long time) {
        stringRedisTemplate.boundListOps(key).expire(time,TimeUnit.MINUTES);
    }
    //删除列表中的多余数据
    public void deleteList(String key,long start,long end ) {
        stringRedisTemplate.opsForList().trim(key,start,end);
    }
    //查询列表指定范围的数据
    public List selectList(String key,long start,long end) {
        return stringRedisTemplate.opsForList().range(key,start,end);
    }
    //查询列表长度
    public long selectListSize(String key) {
        return stringRedisTemplate.opsForList().size(key);
    }
    //获取list
    public List getList(String key) {
        return stringRedisTemplate.opsForList().range(key, 0, -1);
    }
    /**
     * 删除集合中值等于value得元素
     *
     * @param key
     * @param index
     *            index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素;
     *            index<0, 从尾部开始删除第一个值等于value的元素;
     * @param value
     * @return
     */
    public Long lRemove(String key, long index, String value) {
        return stringRedisTemplate.opsForList().remove(key, index, value);
    }
    // rightPop
    public String rightPop(String key) {
        return stringRedisTemplate.boundListOps(key).rightPop();
    }
    // leftPop
    public String leftPop(String key) {
        return stringRedisTemplate.boundListOps(key).leftPop();
    }
    /**
     * 新增一个  sAdd
     *
     * @param key
     * @param value
     */
    public void add(String key, String value) {
        stringRedisTemplate.opsForSet().add(key, value);
    }

    /**
     * 获取所有的values
     * @param key
     * @return
     */
    public Set<String> values(String key) {
        return stringRedisTemplate.opsForSet().members(key);
    }
    /**
     * set移除元素
     *
     * @param key
     * @param values
     * @return
     */
    public Long sRemove(String key, Object... values) {
        return stringRedisTemplate.opsForSet().remove(key, values);
    }
    /**
     * 移除并返回集合的一个随机元素
     *
     * @param key
     * @return
     */
    public String sPop(String key) {
        return stringRedisTemplate.opsForSet().pop(key);
    }
    /**
     * 将元素value从一个集合移到另一个集合
     *
     * @param key
     * @param value
     * @param destKey
     * @return
     */
    public Boolean sMove(String key, String value, String destKey) {
        return stringRedisTemplate.opsForSet().move(key, value, destKey);
    }
    /**
     * 随机获取集合中的一个元素
     *
     * @param key
     * @return
     */
    public String sRandomMember(String key) {
        return stringRedisTemplate.opsForSet().randomMember(key);
    }
    /**
     *
     * @param key
     * @param values
     * @return
     */
    public Boolean zAdd(String key, String values, double score) {

        stringRedisTemplate.opsForZSet().remove(key,values);
        return stringRedisTemplate.opsForZSet().add(key, values,score);
    }
    /**
     * 获取集合的元素, 从小到大排序
     *
     * @param key
     * @param start
     *            开始位置
     * @param end
     *            结束位置, -1查询所有
     * @return
     */
    public Set<String> zRange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().range(key, start, end);
    }
    /**
     * 获取集合的元素, 从小到大排序
     *
     * @param key
     * @param start
     *            开始位置
     * @param end
     *            结束位置, -1查询所有
     * @return
     */
    public Set<String> reverseRange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().reverseRange(key, start, end);
    }


    /**
     * 移除
     * @param key
     * @param values
     * @return
     */
    public Long zRemove(String key, String values) {
        Long remove = stringRedisTemplate.opsForZSet().remove(key, values);
        return remove;
    }
    /**
     * 根据Score值查询集合元素
     *
     * @param key
     * @param min
     *            最小值
     * @param max
     *            最大值
     * @return
     */
    public Set<String> zRangeByScore(String key, double min, double max) {
        return stringRedisTemplate.opsForZSet().rangeByScore(key, min, max);
    }
    /**
     * 获取集合元素, 并且把score值也获取
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<ZSetOperations.TypedTuple<String>> zRangeWithScores(String key, long start,
                                                                   long end) {
        return stringRedisTemplate.opsForZSet().rangeWithScores(key, start, end);
    }


    /**
     * 存入LIst
     * @param key
     * @param list
     */
    public void setList(String key,List list){
        ListOperations  listOperations=redisTemplate.opsForList();
        listOperations.leftPushAll(key,list);
    }

    public List getList1(String key){
        ListOperations  listOperations=redisTemplate.opsForList();
        List list=listOperations.range(key,0,-1);
        return list;
    }

}

